package org.sky.framework.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.sky.framework.degest.TokenEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.gson.Gson;

/**
 * Servlet工具类.
 * 
 * @author gaofu
 *
 */
public class ServletUtil {
	private static final Logger logger = LoggerFactory.getLogger(ServletUtil.class);
	private static final Gson gson = Utils.getGson();

	/**
	 * 取得HttpSession的简化函数.
	 */
	public static HttpSession getSession() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
	}

	/**
	 * 取得HttpRequest的简化函数.
	 */
	public static HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	/**
	 * 取得HttpResponse的简化函数.
	 */
	public static HttpServletResponse getResponse() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
	}

	/**
	 * 取得ServletContext的简化函数.
	 */
	public static ServletContext getServletContext() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession()
				.getServletContext();
	}

	/**
	 * 获得web根目录的物理路径
	 * 
	 * @return rootPath
	 */
	public static String getRootPath() {
		return ClassLoader.getSystemResource("").getPath() + "public";
	}

	/**
	 * 获取servletPath
	 * 
	 * @return
	 */
	public static String getServletPath() {
		HttpServletRequest request = getRequest();
		String servletPath = request.getServletPath();
		if (StringUtils.isEmpty(servletPath)) {
			String contextPath = request.getContextPath();
			String uri = request.getRequestURI();
			servletPath = uri;
			if (!StringUtils.isEmpty(contextPath)) {
				servletPath = uri.substring(contextPath.length());
			}
		}
		return servletPath;
	}

	/**
	 * 获取 HTTP header
	 * 
	 * @return
	 */
	public static Map<String, String> getHeader() {
		HttpServletRequest request = getRequest();
		Map<String, String> map = new HashMap<String, String>();
		Enumeration<String> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String key = headerNames.nextElement();
			String value = request.getHeader(key);
			map.put(key, value);
		}
		return map;
	}

	/**
	 * 获取请求报文
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public static String getRequestBody(HttpServletRequest request) throws Exception {
		return getRequestBody(request, true);
	}

	/**
	 * 获取请求报文
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public static String getRequestBody(HttpServletRequest request, boolean log) throws Exception {
		StringBuilder requestBody = new StringBuilder();
		BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
		String line = null;
		while ((line = in.readLine()) != null) {
			requestBody.append(line.trim());
		}
		if (log) {
			logger.info(getServletPath() + " requestBody: " + requestBody);
		}
		return requestBody.toString();
	}

	/**
	 * 获取请求报文
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String getRequestBody() throws Exception {
		return getRequestBody(getRequest());
	}

	/**
	 * 获取请求bean
	 * 
	 * @param <T>
	 * @param request
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T> T getRequestBody(HttpServletRequest request, Class<T> clazz) throws Exception {
		String requestBody = getRequestBody(request);
		T t = gson.fromJson(requestBody, clazz);
		return t;
	}

	/**
	 * 获取请求bean
	 * 
	 * @param <T>
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T> T getRequestBody(Class<T> clazz) throws Exception {
		return getRequestBody(getRequest(), clazz);
	}

	/**
	 * 设置响应bean
	 * 
	 * @param response
	 * @param obj
	 * @throws Exception
	 */
	public static void setResponseBody(HttpServletResponse response, Object obj) throws Exception {
		String responseBody = gson.toJson(obj);
		logger.info(getServletPath() + " responseBody: " + responseBody);
		response.setContentType("application/json;charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.write(responseBody);
		writer.flush();
		writer.close();
	}

	/**
	 * 设置响应bean
	 * 
	 * @param obj
	 * @throws Exception
	 */
	public static void setResponseBody(Object obj) throws Exception {
		setResponseBody(getResponse(), obj);
	}

	/**
	 * 获取用户请求传递的token
	 * 
	 * @return
	 */
	public static TokenEntity getAuthToken() {
		return (TokenEntity) getRequest().getAttribute(OAuthUtils.Iauthorization);
	}

}
